/*-
 * #%L
 * HAPI FHIR - Docs
 * %%
 * Copyright (C) 2014 - 2025 Smile CDR, Inc.
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package ca.uhn.hapi.fhir.docs;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.parser.IParser;
import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.HumanName;
import org.hl7.fhir.r4.model.Identifier;
import org.hl7.fhir.r4.model.Observation;
import org.hl7.fhir.r4.model.Patient;

public class FhirContextIntro {

	@SuppressWarnings("unused")
	public static void creatingContext() {
		// START SNIPPET: creatingContext
		// Create a context for DSTU2
		FhirContext ctxDstu2 = FhirContext.forDstu2();

		// Alternately, create a context for R4
		FhirContext ctxR4 = FhirContext.forR4();
		// END SNIPPET: creatingContext
	}

	@SuppressWarnings("unused")
	public static void creatingContextHl7org() {
		// START SNIPPET: creatingContextHl7org
		// Create a context for DSTU3
		FhirContext ctx = FhirContext.forDstu3();

		// Working with RI structures is similar to how it works with the HAPI structures
		org.hl7.fhir.dstu3.model.Patient patient = new org.hl7.fhir.dstu3.model.Patient();
		patient.addName().addGiven("John").setFamily("Smith");
		patient.getBirthDateElement().setValueAsString("1998-02-22");

		// Parsing and encoding works the same way too
		String encoded = ctx.newJsonParser().encodeResourceToString(patient);

		// END SNIPPET: creatingContextHl7org
	}

	public void encodeMsg() throws DataFormatException {
		FhirContext ctx = new FhirContext(Patient.class, Observation.class);
		// START SNIPPET: encodeMsg

		/**
		 * FHIR model types in HAPI are simple POJOs. To create a new
		 * one, invoke the default constructor and then
		 * start populating values.
		 */
		Patient patient = new Patient();

		// Add an MRN (a patient identifier)
		Identifier id = patient.addIdentifier();
		id.setSystem("http://example.com/fictitious-mrns");
		id.setValue("MRN001");

		// Add a name
		HumanName name = patient.addName();
		name.setUse(HumanName.NameUse.OFFICIAL);
		name.setFamily("Tester");
		name.addGiven("John");
		name.addGiven("Q");

		// We can now use a parser to encode this resource into a string.
		String encoded = ctx.newXmlParser().encodeResourceToString(patient);
		System.out.println(encoded);
		// END SNIPPET: encodeMsg

		// START SNIPPET: encodeMsgJson
		IParser jsonParser = ctx.newJsonParser();
		jsonParser.setPrettyPrint(true);
		encoded = jsonParser.encodeResourceToString(patient);
		System.out.println(encoded);
		// END SNIPPET: encodeMsgJson

	}

	public void fluent() throws DataFormatException {
		FhirContext ctx = new FhirContext(Patient.class, Observation.class);
		String encoded;
		// START SNIPPET: encodeMsgFluent
		Patient patient = new Patient();
		patient.addIdentifier().setSystem("http://example.com/fictitious-mrns").setValue("MRN001");
		patient.addName()
				.setUse(HumanName.NameUse.OFFICIAL)
				.setFamily("Tester")
				.addGiven("John")
				.addGiven("Q");

		encoded = ctx.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient);
		System.out.println(encoded);
		// END SNIPPET: encodeMsgFluent

	}

	public static void parseMsg() {
		FhirContext ctx = FhirContext.forR4();

		// START SNIPPET: parseMsg
		// The following is an example Patient resource
		String msgString = "<Patient xmlns=\"http://hl7.org/fhir\">"
				+ "<text><status value=\"generated\" /><div xmlns=\"http://www.w3.org/1999/xhtml\">John Cardinal</div></text>"
				+ "<identifier><system value=\"http://orionhealth.com/mrn\" /><value value=\"PRP1660\" /></identifier>"
				+ "<name><use value=\"official\" /><family value=\"Cardinal\" /><given value=\"John\" /></name>"
				+ "<gender><coding><system value=\"http://hl7.org/fhir/v3/AdministrativeGender\" /><code value=\"M\" /></coding></gender>"
				+ "<address><use value=\"home\" /><line value=\"2222 Home Street\" /></address><active value=\"true\" />"
				+ "</Patient>";

		// The hapi context object is used to create a new XML parser
		// instance. The parser can then be used to parse (or unmarshall) the
		// string message into a Patient object
		IParser parser = ctx.newXmlParser();
		Patient patient = parser.parseResource(Patient.class, msgString);

		// The patient object has accessor methods to retrieve all of the
		// data which has been parsed into the instance.
		String patientId = patient.getIdentifier().get(0).getValue();
		String familyName = patient.getName().get(0).getFamily();
		Enumerations.AdministrativeGender gender = patient.getGender();

		System.out.println(patientId); // PRP1660
		System.out.println(familyName); // Cardinal
		System.out.println(gender.toCode()); // male
		// END SNIPPET: parseMsg

	}
}
